OpenCV边缘检测:filter2D和prewwit算子

Filter2D函数:

CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth,
                            InputArray kernel, Point anchor=Point(-1,-1),
                            double delta=0, int borderType=BORDER_DEFAULT );
参数说明:
    InputArray src: 输入图像
    OutputArray dst: 输出图像,和输入图像具有相同的尺寸和通道数量
    int ddepth: 目标图像深度,如果没写将生成与原图像深度相同的图像。原图像和目标图像支持的图像深度如下:
        src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F
        src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F
        src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F
        src.depth() = CV_64F, ddepth = -1/CV_64F
    当ddepth输入值为-1时,目标图像和原图像深度保持一致。
    InputArray kernel:卷积核(或者是相关核),一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的kernel,可以先使用split()函数将图像通道事先分开。
    Point anchor: 内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。
    double delta: 在储存目标图像前可选的添加到像素的值,默认值为0
    int borderType: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
该函数使用于任意线性滤波器的图像,支持就地操作。当其中心移动到图像外,函数可以根据指定的边界模式进行插值运算。函数实质上是计算kernel与图像的相关性而不是卷积 ![Filter2D](http://img.blog.csdn.net/20131110140727656) 也就是说kernel并不是中心点的镜像,如果需要一个正真的卷积,使用函数flip()并将中心点设置为(kernel.cols - anchor.x - 1, kernel.rows - anchor.y -1). 该函数在大核(11x11或更大)的情况下使用基于DFT的算法,而在小核情况下使用直接算法(使用createLinearFilter()检索得到). ### prewwit算子 加入均值处理,对噪声有一定抑制作用 算法实现如下:
Kernelx = (Mat_(3, 3) << 1, 1, 1, 0, 0, 0, -1, -1, -1);
Kernely = (Mat_(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
filter2D(gray, grad_x, CV_16S, Kernelx, Point(-1, -1));
filter2D(gray, grad_y, CV_16S, Kernely, Point(-1, -1));
convertScaleAbs(grad_x, abs_grad_x);
convertScaleAbs(grad_y, abs_grad_y);
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);